package org.sws.domain.strategy.service.rule.tree.factory.engine.impl;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.sws.domain.strategy.enums.RuleLogicCheckTypeVO;
import org.sws.domain.strategy.model.valobj.RuleTreeNodeLineVO;
import org.sws.domain.strategy.model.valobj.RuleTreeNodeVO;
import org.sws.domain.strategy.model.valobj.RuleTreeVO;
import org.sws.domain.strategy.service.rule.tree.ILogicTreeNode;
import org.sws.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import org.sws.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author sws
 * @Date 2025/2/25 11:44
 * @description: 规则树引擎
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }

    @Override
    public DefaultTreeFactory.StrategyAwardData process(String userId, Long strategyId, Integer awardId, Date activityEndTime) {
        DefaultTreeFactory.StrategyAwardData strategyAwardData = null;
        // 获取根节点
        String ruleNode = ruleTreeVO.getTreeRootRuleNode();
        // 规则节点map集合
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap();

        // 获取起始节点「根节点记录了第一个要执行的规则」
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(ruleNode);
        while (null != ruleTreeNode){
            // 根据当前节点的规则key 得到规则（决策）节点实现类
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey());
            // 当前规则节点上配置的规则值
            String ruleValue = ruleTreeNode.getRuleValue();
            // 执行规则得到行为动作结果
            DefaultTreeFactory.TreeActionEntity actionEntity = logicTreeNode.logic(userId, strategyId, awardId, ruleValue, activityEndTime);
            RuleLogicCheckTypeVO ruleLogicCheckTypeVO = actionEntity.getRuleLogicCheckType();
            strategyAwardData = actionEntity.getStrategyAwardData();
            log.info("决策树引擎【{}】 node:{} actionInfo:{}", ruleTreeVO.getTreeName(), ruleTreeNode.getRuleKey(), ruleLogicCheckTypeVO.getInfo());

            // 获取下个节点
            ruleNode = getNextNode(ruleLogicCheckTypeVO.getCode(),ruleTreeNode.getTreeNodeLineVOList());
            ruleTreeNode = treeNodeMap.get(ruleNode);

        }
        return strategyAwardData;
    }

    private String getNextNode(String logicCheckTypeCode, List<RuleTreeNodeLineVO> treeNodeLineVOList) {
        log.info("获取规则树下个节点: logicCheckTypeCode:{}, treeNodeLineVOList:{}", logicCheckTypeCode,treeNodeLineVOList);
        if(CollectionUtil.isEmpty(treeNodeLineVOList)){
            //没有后续节点
            return null;
        }
        for (RuleTreeNodeLineVO nodeLine : treeNodeLineVOList) {
            if(decisionLogic(logicCheckTypeCode, nodeLine)){
                return nodeLine.getRuleNodeTo();
            }
        }
        return null;
//        throw new RuntimeException("决策树引擎，nextNode 计算失败，未找到可执行节点！");
    }

    private boolean decisionLogic(String logicCheckTypeCode, RuleTreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case EQUAL:
                return logicCheckTypeCode.equals(nodeLine.getRuleLimitValue().getCode());
            // 以下规则暂时不需要实现
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }
}
